


#include "category.h"
#include "expression.h"



using namespace std;



// Category ::



Category::Category()
    : m_nRefCount(0)
{
}



bool Category::visible() const
{
    // the normal category is visible by default
    return true;    
}



void Category::hasMutated()
{
}



const string &Category::putText( Subject *owner )
{
    return m_Text;
}



bool Category::personal() const
{
    return false;
}



// CatCollection ::



bool CatCollection::empty(Subject *owner)
{
    return m_Subjects.empty();
}



bool CatCollection::one(Subject *owner)
{
    return m_Subjects.size() == 1;
}



uint8_t CatCollection::getCount(Subject *owner)
{
    return uint8_t( m_Subjects.size() );
}



const CollectionSubjects &CatCollection::getSubjects( Subject *subj )
{
    return m_Subjects;
}



// CatAll ::



CatAll::CatAll( CollectionSubjects &subs )
{
    m_pSubjects = &subs;
}



bool CatAll::empty(Subject *owner)
{
    return m_pSubjects->empty();    
}



bool CatAll::one(Subject *owner)
{
    return m_pSubjects->size() == 1;
}



uint8_t CatAll::getCount(Subject *owner)
{
    return m_pSubjects->size();    
}



const CollectionSubjects &CatAll::getSubjects( Subject *subj )
{
    return *m_pSubjects;
}



// CatMutable ::



CatMutable::CatMutable( CollectionSubjects &subs )
    : m_pBaseSubjects( &subs )
{
}



void CatMutable::hasMutated()
{
    refill();
}



bool CatMutable::one(Subject *owner)
{
    // the mutable are hiding the information on their numbers
    return false;
}



bool CatMutable::visible() const
{
    // the mutable are invisible
    return false;    
}




// CatColor ::



CatColor::CatColor( CollectionSubjects &subs, Color::eColor col ) :
    m_Color( col )
{
    // fill in the collection
    for( CollectionSubjects::iterator is = subs.begin(); is != subs.end(); ++is )
    {
        if( (*is)->getColor() == m_Color )
            m_Subjects.push_back( *is );
    }
}



// CatTruth ::



CatTruth::CatTruth( CollectionSubjects &subs ) :
    CatMutable( subs )
{
    refill();
}



void CatTruth::refill()
{
    m_Subjects.clear();
    
    for( CollectionSubjects::iterator is = m_pBaseSubjects->begin(); is != m_pBaseSubjects->end(); ++is )
    {
        if( (*is)->tellsTruth() )
            m_Subjects.push_back( *is );
    }
}



// CatLying ::



CatLying::CatLying( CollectionSubjects &subs ) :
    CatMutable( subs )
{
    refill();
}



void CatLying::refill()
{
    m_Subjects.clear();
    
    for( CollectionSubjects::iterator is = m_pBaseSubjects->begin(); is != m_pBaseSubjects->end(); ++is )
    {
        if( !(*is)->tellsTruth() )
            m_Subjects.push_back( *is );
    }
}
